home *** CD-ROM | disk | FTP | other *** search
/ Precision Software Appli…tions Silver Collection 1 / Precision Software Applications Silver Collection Volume One (PSM) (1993).iso / tutor / cptutt22.arj / CHAP10.TXT < prev    next >
Text File  |  1992-01-20  |  18KB  |  412 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.                                                        Chapter 10
  7.                                                 VIRTUAL FUNCTIONS
  8.  
  9. Once again we are into a completely new topic with terminology
  10. which will be new to you.  If you are new to object oriented
  11. programming, you should follow along in this chapter very carefully
  12. because every attempt has been made to define every detail of this
  13. new and somewhat intimidating topic.  However, if you are well
  14. versed in object oriented programming, simply learning to use C++,
  15. you may wish to skip the first four programs in this chapter and
  16. go directly to the example program named VIRTUAL5.CPP and continue
  17. from there to the end of the chapter.
  18.  
  19. One term which must be defined is polymorphism, a rather large word
  20. that simply means similar when used in the context of object
  21. oriented programming.  Objects are polymorphic if they have some
  22. similarities but are still somewhat different.  We will see how it
  23. is used in the context of object oriented programming as we proceed
  24. through this chapter.
  25.  
  26. We have already studied operator overloading and function
  27. overloading in this tutorial, and they are a subtle form of
  28. polymorphism since in both cases, a single entity is used to refer
  29. to two or more things.  The use of virtual functions can be a great
  30. aid in programming some kinds of projects as you will see in these
  31. two chapters.
  32.  
  33.  
  34. A SIMPLE PROGRAM WITH INHERITANCE
  35. _________________________________________________________________
  36.  
  37. Examine the example program named VIRTUAL1.CPP   ================
  38. for the basic program outline we will use for      VIRTUAL1.CPP
  39. all discussion in this chapter.  Since this      ================
  40. program has nothing to do with virtual
  41. functions, the name may be somewhat misleading.
  42. It is named VIRTUAL1.CPP because it is part of a series of programs
  43. intended to illustrate the use of virtual functions. The last
  44. program in this chapter will illustrate the proper use of virtual
  45. functions.
  46.  
  47. The first program is very simple and you will recognize it as being
  48. somewhat similar to the programs studied in the last chapter except
  49. that this program is greatly simplified in order to effectively
  50. instruct you in the use of a virtual function.  You will notice
  51. that many of the methods from the last chapter have been completely
  52. dropped from this example for simplicity, and a new method has been
  53. added to the parent class, the method named message() in line 8.
  54.  
  55. Throughout this chapter we will be studying the operation of the
  56. method named message() in the base class and the derived classes.
  57.  
  58.                                                         Page 10-1
  59.  
  60.                                    Chapter 10 - Virtual Functions
  61.  
  62. For that reason, there is a method named message() in the car class
  63. as well as in the new class named boat in lines 27 through 32.
  64.  
  65. You will also notice that there is a lack of a method named
  66. message() in the truck class.  This has been done on purpose to
  67. illustrate the use of the virtual method, or if you prefer, you can
  68. refer to it as a virtual function.  You will recall that the method
  69. named message() from the base class is available in the truck class
  70. because the method from the base class is inherited with the
  71. keyword public included in line 19.  You will also notice that the
  72. use of the keyword public in lines 12 and 27 actually do nothing
  73. because the only method available in the base class is also
  74. available in the derived classes.  There are no methods actually
  75. inherited.  Leaving the keyword in the header poses no problem
  76. however, so it will be left there for your study.
  77.  
  78. The method named message() in the base class and in the derived
  79. classes has been kept very simple on purpose.  Once again, we are
  80. interested in the technique of the virtual method rather than a
  81. long complicated example.
  82.  
  83. The main program is as simple as the classes, one object of each
  84. of the classes is declared in lines 37 through 40 and the method
  85. named message() is called once for each object.  The result of
  86. executing the program indicates that the method for each is called
  87. except for the object named semi, which has no method named
  88. message().  As discussed in the last chapter, the method named
  89. message() from the parent class is called and the data output to
  90. the monitor indicates that this did happen since it displays
  91. "Vehicle message" for the object named semi.
  92.  
  93. The data for the objects is of no concern in this chapter so all
  94. data is allowed to default to private type and none is inherited
  95. into the derived classes.  Some of the data is left in the example
  96. program simply to make the classes look like classes.  Based on
  97. your experience with C++ by now, you realize that the data could
  98. be removed since it is not used.
  99.  
  100. After you understand this program, compile and execute it to see
  101. if your compiler gives the same result of execution.
  102.  
  103.  
  104. ADDING THE KEYWORD VIRTUAL
  105. _________________________________________________________________
  106.  
  107. As you examine the next example program named    ================
  108. VIRTUAL2.CPP, you will notice that there is one    VIRTUAL2.CPP
  109. small change in line 8.  The keyword virtual has ================
  110. been added to the declaration of the method
  111. named message() in the parent class.
  112.  
  113. It may be a bit of a disappointment to you to learn that this
  114. program operates no differently than the last example program.
  115. This is because we are using objects directly and virtual methods
  116.  
  117.                                                         Page 10-2
  118.  
  119.                                    Chapter 10 - Virtual Functions
  120.  
  121. have nothing to do with objects, only with pointers to objects as
  122. we will see soon.  There is an additional comment in line 46
  123. illustrating that since all four objects are of different classes,
  124. it is impossible to assign any object to any other object in this
  125. program.  We will soon see that some pointer assignments are
  126. permitted between objects.
  127.  
  128. After you are sure that the fact that they are virtual functions,
  129. or methods, has nothing to do with the objects as they are
  130. instantiated, compile and execute this example program to see if
  131. your compiler results in the same output as that listed.
  132.  
  133.  
  134. USING OBJECT POINTERS
  135. _________________________________________________________________
  136.  
  137. Examine the example program named VIRTUAL3.CPP   ================
  138. and you will find a repeat of the first program    VIRTUAL3.CPP
  139. but with a different main program.               ================
  140.  
  141. In this program the keyword virtual has been
  142. removed from the method declaration in the parent class in line 8,
  143. and the main program declares pointers to the objects rather than
  144. declaring the objects themselves in lines 37 through 40.  Since we
  145. only declared pointers to the objects we find it necessary to
  146. allocate the objects before using them by using the new operator
  147. in lines 42 through 49.  Upon running the program, we find that
  148. even though we are using pointers to the objects we have done
  149. nothing different than what we did in the first program.  Upon
  150. execution, we find that the program operates in exactly the same
  151. manner as the first example program in this chapter.  This should
  152. not be surprising because a pointer to a method can be used to
  153. operate on an object in the same manner as an object can be
  154. manipulated.
  155.  
  156. Be sure to compile and execute this program before continuing on
  157. to the next example program.  The observant student will notice
  158. that we failed to deallocate the objects prior to terminating the
  159. program.  As always, in such a simple program, it doesn't matter
  160. because the heap will be cleaned up automatically when we return
  161. to the operating system.
  162.  
  163.  
  164. A POINTER AND A VIRTUAL FUNCTION
  165. _________________________________________________________________
  166.  
  167. The example program named VIRTUAL4.CPP is        ================
  168. identical to the last program except for the       VIRTUAL4.CPP
  169. addition of the keyword virtual to line 8 once   ================
  170. again.
  171.  
  172. I hope you are not terribly disappointed to find that this program,
  173. including the keyword virtual, is still identical to the last
  174. program.  Once again we are simply using pointers to each of the
  175.  
  176.                                                         Page 10-3
  177.  
  178.                                    Chapter 10 - Virtual Functions
  179.  
  180. objects, and in every case the pointer is of the same type as the
  181. object to which it points.  You will begin to see some changes in
  182. the next example program, so be patient, we are almost there.
  183.  
  184. Once again, it would be best for you to compile and execute this
  185. program.
  186.  
  187. The four previous programs were meant to instruct you in what
  188. virtual functions do not do.  The next two will show you what
  189. virtual functions do.
  190.  
  191.  
  192.  
  193. A SINGLE POINTER TO THE PARENT CLASS
  194. _________________________________________________________________
  195.  
  196. Examine the example program named VIRTUAL5.CPP   ================
  197. where we almost use a virtual method.  Be just     VIRTUAL5.CPP
  198. a little patient because we are almost ready to  ================
  199. actually use a virtual method.
  200.  
  201. You will notice that this is another copy of our program with the
  202. keyword virtual omitted from line 8 and with a totally different
  203. main program.  In this program, we only declare a single pointer
  204. to a class and the pointer is pointing to the base class of the
  205. class hierarchy.  We will use the single pointer to refer to each
  206. of the four classes and observe what the output of the method named
  207. message() is.
  208.  
  209. A little digression is in order to understand how we can use a
  210. pointer which has been declared to point to one class, to actually
  211. refer to another class.  If we referred to a vehicle (in the real
  212. world, not necessarily in this program), we could be referring to
  213. a car, a truck, a motorcycle, or any other kinds of transportation,
  214. because we are referring to a very general form of an object.  If
  215. however, we were to refer to a car, we are excluding trucks,
  216. motorcycles, and all other kinds of transportation, because we are
  217. referring to a car specifically.  The more general term of vehicle
  218. can therefore refer to many kinds of vehicles, but the more
  219. specific term of car can only refer to a single kind of vehicle,
  220. namely a car.
  221.  
  222. We can apply the same thought process in C++ and say that if we
  223. have a pointer to a vehicle (remembering that a pointer is actually
  224. a reference), we can use that pointer to refer to any of the more
  225. specific objects, and that is indeed legal in C++ according to the
  226. definition of the language.  In a like manner, if we have a pointer
  227. to a car, we cannot use that pointer to reference any of the other
  228. classes including the vehicle class because the pointer to the car
  229. class is too specific and restricted to be used on any of the other
  230. classes.
  231.  
  232.  
  233.  
  234.  
  235.                                                         Page 10-4
  236.  
  237.                                    Chapter 10 - Virtual Functions
  238.  
  239. THE C++ POINTER RULE
  240. _________________________________________________________________
  241.  
  242. The rule as given in C++ terms is as follows.  A pointer declared
  243. as pointing to a base class can be used to point to an object of
  244. a derived class of that base class, but a pointer to a derived
  245. class cannot be used to point to an object of the base class or to
  246. any of the other derived classes of the base class.  In our program
  247. therefore, we are allowed to declare a pointer to the vehicle class
  248. which is the base class, and use that pointer to refer to objects
  249. of either the base class or any of the derived classes.
  250.  
  251. This is exactly what we do in the main program.  We declare a
  252. single pointer which points to the vehicle class and use it to
  253. point to objects of each of the classes in the same order as in the
  254. last four programs.  In each case, we allocate the object, send a
  255. message to the method named message() and deallocate the object
  256. before going on to the next class.  You will notice that when we
  257. send the four messages, we are sending the message to the same
  258. method, namely the method named message() which is a part of the
  259. vehicle base class.  This is because the pointer has a class
  260. associated with it.  Even though the pointer is actually pointing
  261. to four different classes in this program, the program acts as if
  262. the pointer is always pointing to an object of the parent class
  263. because the pointer is of the type of the parent class.
  264.  
  265. The next program will finally do something you have not seen in any
  266. C program or in any C++ program in this tutorial up to this point.
  267. After you compile and execute the current program, we will go on
  268. to study our first virtual function.
  269.  
  270.  
  271.  
  272. AN ACTUAL VIRTUAL FUNCTION
  273. _________________________________________________________________
  274.  
  275. We finally come to an example program with a     ================
  276. virtual function that operates as a virtual        VIRTUAL6.CPP
  277. function and exhibits dynamic binding or         ================
  278. polymorphism as it is called.  This is in the
  279. program named VIRTUAL6.CPP.
  280.  
  281. This program is identical to the last example program except that
  282. the keyword virtual is added to line 8 to make the method named
  283. message() a virtual function.  You will notice that the keyword
  284. virtual only appears in the base class, all classes that derive
  285. this class will have the corresponding method automatically
  286. declared virtual by the system.  In this program, we will once
  287. again use the single pointer to the base class and allocate, use,
  288. then delete an object of each of the four available classes using
  289. the identical code we used in the last program.  However, because
  290. of the addition of the keyword virtual in line 8, this program acts
  291. entirely different from the last example program.
  292.  
  293.  
  294.                                                         Page 10-5
  295.  
  296.                                    Chapter 10 - Virtual Functions
  297.  
  298.  
  299. Since the method named message() is declared to be a virtual method
  300. in its declaration in the base class, anytime we refer to this
  301. method with a pointer to the base class, we actually execute the
  302. method associated with one of the derived classes if there is a
  303. method available in the derived class and if the pointer is
  304. actually pointing to that derived class.  When the program is
  305. executed, the output reflects the same output we saw in the other
  306. cases when we were actually calling the methods in the derived
  307. classes, but now we are using a pointer of the base class type to
  308. make the calls.
  309.  
  310. You will notice that in lines 40, 44, 48, and 52, even though the
  311. code is identical in each line, the system is making the decision
  312. of which method to actually call based on the type of the pointer
  313. when each message is sent.  The decision of which method to call
  314. is not made during the time when the code is compiled but when the
  315. code is executed.  This is dynamic binding and can be very useful
  316. in some programming situations.  In fact, there are only three
  317. different calls made because the class named truck does not have
  318. a method named message(), so the system simply uses the method from
  319. the base class to satisfy the message passed.  For this reason, a
  320. virtual function must have an implementation available in the base
  321. class which will be used if there is not one available in one or
  322. more of the derived classes.  Note that the message is actually
  323. sent to a pointer to the object, but this is splitting hairs and
  324. should not be overly emphasized at this time.
  325.  
  326. It is probably not obvious but the observant student will note that
  327. the structure of the virtual function in the base class and each
  328. of the derived classes is identical.  The return type and the
  329. number and types of the parameters must be identical for all since
  330. a single statement can be used to call any of them.
  331.  
  332.  
  333.  
  334. IS THIS REALLY SIGNIFICANT?
  335. _________________________________________________________________
  336.  
  337. This program probably does not seem to do much when you first
  338. approach it, but the dynamic binding is a very useful construct and
  339. will be illustrated in the next chapter with a rather simple
  340. program that uses the technique of dynamic binding to implement a
  341. personnel list for a small company.
  342.  
  343. If the keyword virtual is used, the system will use late binding
  344. which is done at run time, but if the keyword is not included,
  345. early binding will be used.  What these words actually mean is that
  346. with late binding, the compiler does not know which method will
  347. actually respond to the message because the type of the pointer is
  348. not known at compile time.  With early binding, however, the
  349. compiler decides at compile time what method will respond to the
  350. message sent to the pointer.
  351.  
  352.  
  353.                                                         Page 10-6
  354.  
  355.                                    Chapter 10 - Virtual Functions
  356.  
  357. Be sure to compile and execute this example program before
  358. continuing on to the next chapter where we will see a practical
  359. example of the use of this technique.
  360.  
  361.  
  362.  
  363. PROGRAMMING EXERCISES
  364. _________________________________________________________________
  365.  
  366. 1.   Modify VIRTUAL3.CPP to deallocate the objects prior to
  367.      terminating the program.
  368.  
  369. 2.   Add a message() method to the truck class of VIRTUAL6.CPP to
  370.      observe the use of the new method instead of defaulting to the
  371.      parent class method.
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.                                                         Page 10-7